package com.atguigu.spzx.manager.service.impl;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.atguigu.spzx.common.exception.GuiguException;
import com.atguigu.spzx.manager.mapper.SysUserMapper;
import com.atguigu.spzx.manager.service.SysUserService;
import com.atguigu.spzx.model.dto.system.LoginDto;
import com.atguigu.spzx.model.entity.system.SysUser;
import com.atguigu.spzx.model.vo.common.ResultCodeEnum;
import com.atguigu.spzx.model.vo.system.LoginVo;
import com.atguigu.spzx.utils.AuthContextUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.concurrent.TimeUnit;

import static com.atguigu.spzx.manager.constants.RedisConstants.LOGIN_USERINFO_KEY;
import static com.atguigu.spzx.manager.constants.RedisConstants.LOGIN_VALIDATE_KEY;

@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public LoginVo login(LoginDto loginDto) {
        // 1.获取提交用户名
        String userName = loginDto.getUserName();
        // 2.根据用户名查询数据库表  sys_user表
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUsername, userName);
        SysUser sysUser = this.getOne(queryWrapper);

        // 3.如果根据用户名查不到信息，用户不存在，返回错误信息
        if (sysUser == null) {
            throw new GuiguException(ResultCodeEnum.LOGIN_ERROR);
        }

        // 4.根据用户名查询到用户信息，用户存在
        String dbPassword = sysUser.getPassword();
        String inputPassword = DigestUtils.md5DigestAsHex(loginDto.getPassword().getBytes());
        // 5.比较密码
        if (!inputPassword.equals(dbPassword)) {
            throw new GuiguException(ResultCodeEnum.LOGIN_ERROR);
        }

        // 校验验证码是否正确
        String captcha = loginDto.getCaptcha();     // 用户输入的验证码
        String codeKey = loginDto.getCodeKey();     // redis中验证码的数据key

        // 从Redis中获取验证码
        String redisCode = stringRedisTemplate.opsForValue().get(LOGIN_VALIDATE_KEY + codeKey);
        if(StrUtil.isEmpty(redisCode) || !StrUtil.equalsIgnoreCase(redisCode , captcha)) {
            throw new GuiguException(ResultCodeEnum.VALIDATECODE_ERROR) ;
        }

        // 验证通过删除redis中的验证码
        stringRedisTemplate.delete(LOGIN_VALIDATE_KEY + codeKey) ;

        // 6.登录成功
        String token = UUID.randomUUID().toString().replaceAll("-", "");

        // 7.把登录成功用户信息放到redis里面
        String jsonString = JSON.toJSONString(sysUser);
        stringRedisTemplate.opsForValue().set(LOGIN_USERINFO_KEY + token, jsonString, 7, TimeUnit.DAYS);

        // 8.返回loginVo对象
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        return loginVo;
    }

    @Override
    public SysUser getUserInfo() {
        //String bearer = token.replace("Bearer ", "");
        //String userJson = stringRedisTemplate.opsForValue().get(LOGIN_USERINFO_KEY + bearer);
        //return JSON.parseObject(userJson , SysUser.class);

        return AuthContextUtil.get();
    }

    @Override
    public void logout(String token) {
        String bearer = token.replace("Bearer ", "");
        stringRedisTemplate.delete(LOGIN_USERINFO_KEY + bearer) ;
    }
}
